﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            this.DoubleBuffered = true;
            InitializeComponent();
            Paint += new PaintEventHandler(Form1_Paint);
            Shown += new EventHandler(Form1_Shown);
        }

        public enum Field {L = 11, M = 9, S = 7};

        public static class Settings
        {
            public static void ChangeField(Field e)
             {
                 CellField = e;
                 row = (int)CellField;
                 number = (row + 1) * (row + 1) + row * row;
             }
            public static int r { get { return row; } }
            public static int dr { get { return 11 - row; } }
            public static int n { get { return number; } }
            private static int number = 265;
            private static int row = 11;
            private static Field CellField;
        }

        public const int s = 20;
        public const int initial = 265;
        //public const int n = initial - 84;
		//public int r = 2;
        public int GNumber1 = 0;
        public Cell[] CellArray = new Cell[initial];
        public Point GetLocalMousePos = new Point();
        public enum Stick { T, L, All, Empty }
        public bool drawn = false;

        public class StickAppearedEventArgs : EventArgs
        {
            public StickAppearedEventArgs(Stick s, int Number) { this.s = s; this.Number = Number; }
            public readonly Stick s;
            public readonly int Number;
        }
       
        public class Cell
        {
            public Cell(Point P) { CellXY = P; CS = CellState.Empty; CellStick = Stick.Empty; ClearQuantity(); Number = Quantity; ++Quantity; }
            public Cell() { CellXY.X = 0; CellXY.Y = 0; CS = CellState.Empty; CellStick = Stick.Empty; ClearQuantity();  }

            public enum CellState { X, O, Empty };

            public void SetStick(Stick C)
            {

                if (CellStick == Stick.Empty)
                {
                    CellStick = C;
                    var e = new StickAppearedEventArgs(this.GetStick(), this.Number);
                    if (C == Stick.T) OnTopStickAppeared(e); else OnLeftStickAppeared(e);
                    Player = !Player;
                    this.State_Decide();
                };

                if (CellStick == Stick.L && C == Stick.T)
                {

                    CellStick = Stick.All;
                    var e = new StickAppearedEventArgs(this.GetStick(), this.Number);
                    OnTopStickAppeared(e);
                    Player = !Player;
                    this.State_Decide();

                }

                if (CellStick == Stick.T && C == Stick.L)
                {
                    CellStick = Stick.All;
                    var e = new StickAppearedEventArgs(this.GetStick(), this.Number);
                    OnLeftStickAppeared(e);
                    Player = !Player;
                    this.State_Decide();

                }
                

            }

            public void drawCell(PaintEventArgs e)
            {
                switch (CellStick)
                {
                    case Stick.All: e.Graphics.DrawLine(new Pen(Color.Blue), CellXYToFormXY(), new Point(CellXYToFormXY().X + s, CellXYToFormXY().Y));
                        e.Graphics.DrawLine(new Pen(Color.Blue), CellXYToFormXY(), new Point(CellXYToFormXY().X, CellXYToFormXY().Y + s));
                        break;
                    case Stick.L: e.Graphics.DrawLine(new Pen(Color.Blue), CellXYToFormXY(), new Point(CellXYToFormXY().X, CellXYToFormXY().Y + s));
                        break;
                    case Stick.T: e.Graphics.DrawLine(new Pen(Color.Blue), CellXYToFormXY(), new Point(CellXYToFormXY().X + s, CellXYToFormXY().Y));
                        break;
                }
                if (CS == CellState.X)
                {
                    e.Graphics.DrawLine(new Pen(Color.Blue), new Point(CellXYToFormXY().X + s / 10+2, CellXYToFormXY().Y + s / 10+2), new Point(CellXYToFormXY().X + s - s / 10-2, CellXYToFormXY().Y + s - s / 10-2));
                    e.Graphics.DrawLine(new Pen(Color.Blue), new Point(CellXYToFormXY().X + s / 10+2, CellXYToFormXY().Y - s / 10 -2 + s), new Point(CellXYToFormXY().X + s - s / 10-2, CellXYToFormXY().Y +  s / 10+2));
                
                }
                if (CS == CellState.O) e.Graphics.DrawEllipse(new Pen(Color.Blue), CellXYToFormXY().X + s / 10, CellXYToFormXY().Y + s / 10, (s - 2 * s / 10), (s - 2 * s / 10));
            }


            public Stick GetStick() { return CellStick; }

            public void ChangeCellState(bool B)
            {
                if (CS == CellState.Empty)
                {
                    CS = (B) ? CellState.X  : CellState.O;
                   
                    if(B) QuantityXO[1]++; else QuantityXO[0]++;
                    Player = !Player;
                }
            }

            private byte SurroundedSticks = 0;

            private void State_Decide()
            {
                //if((SurroundedSticks==2)&&(this.GetStick()==Stick.All)) ChangeCellState(Player);
            }

            private void State_Decide(object sender, StickAppearedEventArgs e)
            {
                SurroundedSticks++;
                //if((SurroundedSticks==2)&&(this.GetStick()==Stick.All)) ChangeCellState(Player);
            }

            public void Listen(Cell c)
            {
                if(c.Number == this.Number+1)c.LeftStickAppeared += new StickAppearedEventHandler(State_Decide);
                else c.TopStickAppeared += new StickAppearedEventHandler(State_Decide);
            }

            protected virtual void OnLeftStickAppeared(StickAppearedEventArgs e)
            {
                if (LeftStickAppeared != null)
                {
                    LeftStickAppeared(this, e);
                }
            }
            protected virtual void OnTopStickAppeared(StickAppearedEventArgs e)
            {
                if (TopStickAppeared != null)
                {
                    TopStickAppeared(this, e);
                }
            }

            public void ClearQuantity()
            {
                QuantityXO[1] = 0;
                QuantityXO[0] = 0;
            }

            public delegate void StickAppearedEventHandler(object sender, StickAppearedEventArgs e);
            public event StickAppearedEventHandler LeftStickAppeared;
            public event StickAppearedEventHandler TopStickAppeared;
            public static int Quantity = 0;
            public readonly int Number;
            public CellState GetCellState() { return CS; }
            public static bool Player = true;
            public Point CellXYToFormXY() {return new Point(CellXY.X * s, CellXY.Y * s);}
            public Point GetCellXY() { return CellXY; }
            protected Point CellXY;
            protected Stick CellStick;
            protected CellState CS;
            public static int[] QuantityXO = new int[2];

        }

        public void DisplayOX()
        {
            //for (int i = 0; i < n; i++) CellArray[i].CheckQuantity();
            label1.Text = "X: " + Cell.QuantityXO[1].ToString() + " O: " + Cell.QuantityXO[0].ToString() + "; " + ((!Cell.Player) ? "X" : "O") + " now";//; M: " + GC.GetTotalMemory(false).ToString();

        }


        public int SearchCell(Point P)
        {
            int i = 0;
            for (i = 0; i < Settings.n; i++)
            {
                if (P == CellArray[i].GetCellXY()) break;
            };

            return ((i == 0) || (i == Settings.n)) ? -1 : i;
        }

        public int SearchCell(MouseEventArgs e)
        {
            int i = 0;
            Point P = new Point(e.X, e.Y);
            for (i = 0; i < Settings.n; i++)
            {
                if (P == CellArray[i].GetCellXY()) break;
            };
            
            return ((i==0)||(i==Settings.n))?-1:i;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            FormBorderStyle = FormBorderStyle.Fixed3D;
            Settings.ChangeField(Field.S);
            
            //Point P = new Point(0, 0);
            //int h = 0;
            //for (int i = 0; i < 11; i++)
            //    for (int j = 1; j < 2 + 2 * i; j++)
            //    { P.X = 12 + j - i - 1; P.Y = i + 1; CellArray[h] = new Cell(P); h++; }
            ////
            //for (int i = 0; i < 23; i++) { P.X = 1 + i; P.Y = 12; CellArray[h] = new Cell(P); h++; }
            //int g = 12;
            //for (int i = 11; i > 0; i--)
            //{
            //    g++;
            //    for (int j = 2; j < 1 + 2 * i; j++)
            //    { P.X = 12 + j - i - 1; P.Y = g; CellArray[h] = new Cell(P); h++; }
            //}

            
            const int cx = 2, cy = 4;
			
            Point P = new Point(0, 0);
            int h = 0;
            for (int i = 0; i < Settings.r; i++)
                for (int j = 1; j < 2 + 2 * i; j++)
                { P.X = 12 + j - i - 1 + cx;
                  P.Y = i + 1 + cy; 
                    CellArray[h] = new Cell(P); 
                    if (side(h,1)) CellArray[h].SetStick(Stick.All);
                    if (side(h, 2)) CellArray[h].SetStick(Stick.T);
                    h++; 
                }
            //
            for (int i = 0; i < 2 * Settings.r + 1; i++) { P.X = 1 + i + cx + Settings.dr; P.Y = 12 + cy - Settings.dr; CellArray[h] = new Cell(P); h++; }
            int g = Settings.r + 1;
            for (int i = Settings.r; i > 0; i--)
            {
                g++;
                for (int j = 2; j < 1 + 2 * i; j++)
                { P.X = 12 + j - i - 1 + cx; 
                    P.Y = g + cy; 
                    CellArray[h] = new Cell(P); 
                    if (side(h,3)) 
                        CellArray[h].SetStick(Stick.L); 
                    h++; 
                }
            }
            for (int i = 0; i < Settings.n; i++)
            {
                int Number2 = SearchCell(new Point(CellArray[i].GetCellXY().X, CellArray[i].GetCellXY().Y + 1));
                if (Number2 != -1) CellArray[i].Listen(CellArray[Number2]);
                if (!side(i,2)&&!side(i,4)) CellArray[i].Listen(CellArray[i+1]);
            }
        }

        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {

        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            Point P = new Point((int)Math.Floor((double)e.X / s), (int)Math.Floor((double)e.Y / s));
            label1.Text = "X: " + e.X.ToString() + " Y: " + e.Y.ToString() + 
                " N: " + SearchCell(P).ToString() + " M: " + CellArray[(SearchCell(P)!=-1)?SearchCell(P):Settings.n-1].Number;
            if (e.Button == MouseButtons.Left && validCell(GNumber1) && (CellArray[GNumber1].GetCellState() == Cell.CellState.Empty))
            {
            System.Drawing.Graphics graphics;
            graphics = this.CreateGraphics();
            Pen pen = new Pen(Color.Green, 2);
            if ((MouseOnRectOver(e.X, e.Y, 1) || (!MouseOnRectOver(e.X, e.Y, 2) && !MouseOnRectOver(e.X, e.Y, 3) && !MouseOnRectOver(e.X, e.Y, 5)) && !MouseOnRectOver(e.X, e.Y, 6)) && drawn) 
            { 
                PlayerHelper(); 
                drawn = false; 
            };
            if (MouseOnRectOver(e.X, e.Y, 2) && !side(GNumber1, 3) && !side(GNumber1, 4)) 
            {
                graphics.DrawLine(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2 * s, CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2 * s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2 * s); 
                drawn = true; 
            };
            if (MouseOnRectOver(e.X, e.Y, 3) && !side(GNumber1, 1) && !side(GNumber1, 2)) 
            { 
                graphics.DrawLine(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 , CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2 * s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2); 
                drawn = true; 
            };
            if (MouseOnRectOver(e.X, e.Y, 5) && !side(GNumber1, 1) && !side(GNumber1, 3)) 
            { 
                graphics.DrawLine(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2*s); 
                drawn = true; 
            };
            if (MouseOnRectOver(e.X, e.Y, 6) && !side(GNumber1, 2) && !side(GNumber1, 4)) 
            { 
                graphics.DrawLine(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2*s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2*s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2 * s); 
                drawn = true; 
            };


            }
        }

        public bool MouseOnRectOver(int x, int y, int No)
        {
            bool hor = (y>CellArray[GNumber1].CellXYToFormXY().Y - s / 2)&&(y<CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2 * s);
            bool vert = (x>CellArray[GNumber1].CellXYToFormXY().X - s / 2)&&(x<CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2 * s);

            switch (No)
            {
                case 1: return (hor && vert) ? true : false;
                case 2: return (vert && (y > CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2 * s) && (y < CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 4 * s))? true : false;
                case 3: return (vert && (y > CellArray[GNumber1].CellXYToFormXY().Y - s / 2 - 2 * s) && (y < CellArray[GNumber1].CellXYToFormXY().Y - s / 2)) ? true : false;
                case 5: return (hor && (x > CellArray[GNumber1].CellXYToFormXY().X - s / 2 - 2 * s) && (x < CellArray[GNumber1].CellXYToFormXY().X - s / 2)) ? true : false;
                case 6: return (hor && (x > CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2 * s) && (x < CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 4 * s)) ? true : false;
                default: return false;
            }
        }

        public void PlayerHelper()
        {
            System.Drawing.Graphics graphics;
            graphics = this.CreateGraphics();
            Pen pen = new Pen(Color.Aqua, 2);
            SolidBrush b = new SolidBrush(Color.White);
            graphics.FillRectangle(b, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, 2 * s, 2 * s);
            graphics.DrawRectangle(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, 2 * s, 2 * s);
            if (!side(GNumber1, 1) && !side(GNumber1, 3))
            {
                graphics.FillRectangle(b, CellArray[GNumber1].CellXYToFormXY().X - s / 2 - 2 * s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, 2 * s, 2 * s);
                graphics.DrawRectangle(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2 - 2 * s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, 2 * s, 2 * s);
            }
            if (!side(GNumber1, 2) && !side(GNumber1, 4))
            {
                graphics.FillRectangle(b, CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2 * s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, 2 * s, 2 * s);
                graphics.DrawRectangle(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2 + 2 * s, CellArray[GNumber1].CellXYToFormXY().Y - s / 2, 2 * s, 2 * s);
            }
            if (!side(GNumber1, 1) && !side(GNumber1, 2))
            {
                graphics.FillRectangle(b, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 - 2 * s, 2 * s, 2 * s);
                graphics.DrawRectangle(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 - 2 * s, 2 * s, 2 * s);
            }

            if (!side(GNumber1, 3) && !side(GNumber1, 4))
            {
                graphics.FillRectangle(b, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2 * s, 2 * s, 2 * s);
                graphics.DrawRectangle(pen, CellArray[GNumber1].CellXYToFormXY().X - s / 2, CellArray[GNumber1].CellXYToFormXY().Y - s / 2 + 2 * s, 2 * s, 2 * s);
            }
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            Point P = new Point((int)Math.Floor((double)e.X / s), (int)Math.Floor((double)e.Y / s));
            if (e.Button == MouseButtons.Left)
            {
                GNumber1 = SearchCell(P);
                if ((validCell(GNumber1)) && (CellArray[GNumber1].GetCellState() == Cell.CellState.Empty)) PlayerHelper();
            }

        }

        private bool side(int Number, int No)
        {
            switch (No)
            {
                case 1: return ((Math.Floor(Math.Sqrt(Number)) == Math.Sqrt(Number)) && (Number <= Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))));
                case 2: return ((Math.Floor(Math.Sqrt(Number + 1)) == Math.Sqrt(Number + 1)) && (Number <= Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2)) - 1));
                case 3: return ((Math.Floor(Math.Sqrt(Settings.n - Number)) == Math.Sqrt(Settings.n - Number)) && (Number >= Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))));
                case 4: return ((Math.Floor(Math.Sqrt(Settings.n - Number - 1)) == Math.Sqrt(Settings.n - Number - 1)) && (Number >= (Settings.n - (10 - Settings.dr) * (10 - Settings.dr)) - 1)); 
                default:  return false;
            }
        }



        private bool side(int Number)
        {
            if (((Math.Floor(Math.Sqrt(Number)) == Math.Sqrt(Number)) && (Number <= Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))))
                || ((Math.Floor(Math.Sqrt(Number + 1)) == Math.Sqrt(Number + 1)) && (Number <= Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2)) - 2))
                || ((Math.Floor(Math.Sqrt(Settings.n - Number)) == Math.Sqrt(Settings.n - Number)) && (Number >= Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))))
                || ((Math.Floor(Math.Sqrt(Settings.n - Number - 1)) == Math.Sqrt(Settings.n - Number - 1)) && (Number >= (Settings.n - (10 - Settings.dr) * (10 - Settings.dr)) - 1)))
                return true;
            else return false;
        }

 

        private bool validCell(int Number1) { return ((Number1 != Settings.n) && (Number1 != 0) && (Number1 != Settings.n) && (Number1 != Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))) && (Number1 != (Settings.n - 1)) && (Number1 != Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2)))); }

        private void MainImplementation(int Number1)
        {
            Point P = new Point((int)Math.Floor((double)GetLocalMousePos.X / s), (int)Math.Floor((double)GetLocalMousePos.Y / s));

            int Number2 = SearchCell(new Point(CellArray[Number1].GetCellXY().X, CellArray[Number1].GetCellXY().Y + 1));
            int Number3 = SearchCell(new Point(CellArray[Number1].GetCellXY().X, CellArray[Number1].GetCellXY().Y - 1));
            int Number4 = SearchCell(new Point(CellArray[Number1].GetCellXY().X, CellArray[Number1].GetCellXY().Y + 2));
            bool forCell1 = false, forCell2 = false, forCell3 = false, forCell1p1 = false, forCell1m1 = false;

            if (!side(Number1, 1) && !side(Number1, 2) && !side(Number1, 3) && !side(Number1, 4))
            {

                forCell1 = ((CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number1 + 1].GetStick() == Stick.L || CellArray[Number1 + 1].GetStick() == Stick.All) && (CellArray[Number2].GetStick() == Stick.T || CellArray[Number2].GetStick() == Stick.All));
                forCell1p1 = ((CellArray[Number1 + 1].GetStick() == Stick.All) && (CellArray[Number1 + 2].GetStick() == Stick.L || CellArray[Number1 + 2].GetStick() == Stick.All) && (CellArray[Number2 + 1].GetStick() == Stick.T || CellArray[Number2 + 1].GetStick() == Stick.All));
                forCell2 = ((CellArray[Number2].GetStick() == Stick.All) && (CellArray[Number2 + 1].GetStick() == Stick.L || CellArray[Number2 + 1].GetStick() == Stick.All) && (CellArray[Number4].GetStick() == Stick.T || CellArray[Number4].GetStick() == Stick.All));
                forCell3 = ((CellArray[Number3].GetStick() == Stick.All) && (CellArray[Number3 + 1].GetStick() == Stick.L || CellArray[Number3 + 1].GetStick() == Stick.All) && (CellArray[Number1].GetStick() == Stick.T || CellArray[Number1].GetStick() == Stick.All));
                forCell1m1 = ((CellArray[Number1 - 1].GetStick() == Stick.All) && (CellArray[Number1].GetStick() == Stick.L || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number2 - 1].GetStick() == Stick.T || CellArray[Number2 - 1].GetStick() == Stick.All));

                if (Number1 == Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2)) - 1)
                {
                    forCell2 = CellArray[Number2].GetStick() == Stick.All;
                    forCell3 = ((CellArray[Number3].GetStick() == Stick.L) && (CellArray[Number1].GetStick() == Stick.T || CellArray[Number1].GetStick() == Stick.All));
                }

                if (Number1 == Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2)) + 1)
                {
                    forCell3 = ((CellArray[Number1].GetStick() == Stick.T || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number3 + 1].GetStick() == Stick.L || CellArray[Number3 + 1].GetStick() == Stick.All));
                    forCell2 = ((CellArray[Number2].GetStick() == Stick.T) && (CellArray[Number2 + 1].GetStick() == Stick.L || CellArray[Number2 + 1].GetStick() == Stick.All));
                }

                if (Number1 == (Settings.n - 3))
                {
                    forCell1m1 = ((CellArray[Number1 - 1].GetStick() == Stick.T) && (CellArray[Number1].GetStick() == Stick.L || CellArray[Number1].GetStick() == Stick.All));
                    forCell1p1 = (CellArray[Number1 + 1].GetStick() == Stick.All);
                };

                if (side(Number1 - 1, 1))
                {
                    forCell3 = ((CellArray[Number1].GetStick() == Stick.T || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number3 + 1].GetStick() == Stick.L || CellArray[Number3 + 1].GetStick() == Stick.All));
                    forCell1m1 = ((CellArray[Number1].GetStick() == Stick.L || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number2 - 1].GetStick() == Stick.T || CellArray[Number2 - 1].GetStick() == Stick.All));
                }

                if (side(Number1 - 1, 3) && !(Number1 == (Settings.n - 3)))
                {
                    forCell2 = ((CellArray[Number2].GetStick() == Stick.T) && (CellArray[Number2 + 1].GetStick() == Stick.L || CellArray[Number2 + 1].GetStick() == Stick.All));
                    forCell1m1 = ((CellArray[Number1].GetStick() == Stick.L || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number1 - 1].GetStick() == Stick.T || CellArray[Number1 - 1].GetStick() == Stick.All));
                }

                if (side(Number1 + 1, 2))
                {
                    forCell3 = ((CellArray[Number1].GetStick() == Stick.T || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number3].GetStick() == Stick.L));
                    forCell1p1 = ((CellArray[Number2 + 1].GetStick() == Stick.T || CellArray[Number2 + 1].GetStick() == Stick.All) && (CellArray[Number1 + 1].GetStick() == Stick.L));
                }

                if (side(Number1 + 1, 4) && !(Number1 == (Settings.n - 3)))
                {
                    forCell2 = ((CellArray[Number2].GetStick() == Stick.All));
                    forCell1p1 = ((CellArray[Number1 + 1].GetStick() == Stick.All));
                }

                if (forCell1 && forCell2 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number2].GetCellState() == Cell.CellState.Empty))
                {
                    CellArray[Number1].ChangeCellState(Cell.Player);
                    Cell.Player = !Cell.Player;
                    CellArray[Number2].ChangeCellState(Cell.Player);
                }

                if (forCell1 && forCell1p1 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number1 + 1].GetCellState() == Cell.CellState.Empty))
                {
                    CellArray[Number1].ChangeCellState(Cell.Player);
                    Cell.Player = !Cell.Player;
                    CellArray[Number1 + 1].ChangeCellState(Cell.Player);
                }

                if (forCell1 && forCell3 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number3].GetCellState() == Cell.CellState.Empty))
                {
                    CellArray[Number1].ChangeCellState(Cell.Player);
                    Cell.Player = !Cell.Player;
                    CellArray[Number3].ChangeCellState(Cell.Player);
                }

                if (forCell1 && forCell1m1 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number1 - 1].GetCellState() == Cell.CellState.Empty))
                {
                    CellArray[Number1].ChangeCellState(Cell.Player);
                    Cell.Player = !Cell.Player;
                    CellArray[Number1 - 1].ChangeCellState(Cell.Player);
                }


            }
            else
            {
                if (side(Number1, 1))
                {
                    forCell1 = ((CellArray[Number1 + 1].GetStick() == Stick.L || CellArray[Number1 + 1].GetStick() == Stick.All) && (CellArray[Number2].GetStick() == Stick.T || CellArray[Number2].GetStick() == Stick.All));
                    forCell2 = ((CellArray[Number2].GetStick() == Stick.All) && (CellArray[Number2 + 1].GetStick() == Stick.L || CellArray[Number2 + 1].GetStick() == Stick.All) && (CellArray[Number4].GetStick() == Stick.T || CellArray[Number4].GetStick() == Stick.All));
                    forCell1p1 = ((CellArray[Number1 + 1].GetStick() == Stick.All) && (CellArray[Number1 + 2].GetStick() == Stick.L || CellArray[Number1 + 2].GetStick() == Stick.All) && (CellArray[Number2 + 1].GetStick() == Stick.T || CellArray[Number2 + 1].GetStick() == Stick.All));
                    if (forCell1 && forCell2 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number2].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number2].ChangeCellState(Cell.Player);
                    }
                    if (forCell1 && forCell1p1 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number1 + 1].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number1 + 1].ChangeCellState(Cell.Player);
                    }
                };
                if (side(Number1, 2))
                {
                    forCell1 = ((CellArray[Number1].GetStick() == Stick.L) && (CellArray[Number2].GetStick() == Stick.T || CellArray[Number2].GetStick() == Stick.All));
                    forCell2 = ((CellArray[Number2].GetStick() == Stick.All) && (CellArray[Number2 + 1].GetStick() == Stick.L || CellArray[Number2 + 1].GetStick() == Stick.All) && (CellArray[Number4].GetStick() == Stick.T || CellArray[Number4].GetStick() == Stick.All));
                    forCell1m1 = ((CellArray[Number1 - 1].GetStick() == Stick.All) && (CellArray[Number1].GetStick() == Stick.L || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number2 - 1].GetStick() == Stick.T || CellArray[Number2 - 1].GetStick() == Stick.All));
                    if (forCell1 && forCell2 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number2].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number2].ChangeCellState(Cell.Player);
                    }
                    if (forCell1 && forCell1m1 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number1 - 1].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number1 - 1].ChangeCellState(Cell.Player);
                    }

                };
                if (side(Number1, 3))
                {
                    int Number2p1 = SearchCell(new Point(CellArray[Number1].GetCellXY().X + 1, CellArray[Number1].GetCellXY().Y + 1));
                    forCell1 = ((CellArray[Number1].GetStick() == Stick.T) && (CellArray[Number1 + 1].GetStick() == Stick.L || CellArray[Number1 + 1].GetStick() == Stick.All));
                    forCell3 = ((CellArray[Number3].GetStick() == Stick.All) && (CellArray[Number3 + 1].GetStick() == Stick.L || CellArray[Number3 + 1].GetStick() == Stick.All) && (CellArray[Number1].GetStick() == Stick.T || CellArray[Number1].GetStick() == Stick.All));
                    forCell1p1 = ((CellArray[Number1 + 1].GetStick() == Stick.All) && (CellArray[Number1 + 2].GetStick() == Stick.L || CellArray[Number1 + 2].GetStick() == Stick.All) && (CellArray[Number2p1].GetStick() == Stick.T));
                    if (forCell1 && forCell1p1 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number1 + 1].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number1 + 1].ChangeCellState(Cell.Player);
                    }
                    if (forCell1 && forCell3 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number3].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number3].ChangeCellState(Cell.Player);
                    }
                };
                if (side(Number1, 4))
                {
                    int Number2m1 = SearchCell(new Point(CellArray[Number1].GetCellXY().X - 1, CellArray[Number1].GetCellXY().Y + 1));
                    forCell1 = (CellArray[Number1].GetStick() == Stick.All);
                    forCell1m1 = ((CellArray[Number1 - 1].GetStick() == Stick.All) && (CellArray[Number1].GetStick() == Stick.L || CellArray[Number1].GetStick() == Stick.All) && (CellArray[Number2m1].GetStick() == Stick.T || CellArray[Number2m1].GetStick() == Stick.All));
                    forCell3 = ((CellArray[Number3].GetStick() == Stick.All) && (CellArray[Number3 + 1].GetStick() == Stick.L || CellArray[Number3 + 1].GetStick() == Stick.All) && (CellArray[Number1].GetStick() == Stick.T || CellArray[Number1].GetStick() == Stick.All));
                    if (forCell1 && forCell3 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number3].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number3].ChangeCellState(Cell.Player);
                    }
                    if (forCell1 && forCell1m1 && (CellArray[Number1].GetCellState() == Cell.CellState.Empty) && (CellArray[Number1 - 1].GetCellState() == Cell.CellState.Empty))
                    {
                        CellArray[Number1].ChangeCellState(Cell.Player);
                        Cell.Player = !Cell.Player;
                        CellArray[Number1 - 1].ChangeCellState(Cell.Player);
                    }

                };

            }

            if (forCell1)
            {
                CellArray[Number1].ChangeCellState(Cell.Player);
            }

            if (forCell1p1)
            {
                CellArray[Number1 + 1].ChangeCellState(Cell.Player);
            }

            if (forCell3)
            {
                CellArray[Number3].ChangeCellState(Cell.Player);
            }

            if (forCell1m1)
            {
                CellArray[Number1 - 1].ChangeCellState(Cell.Player);

            }

            if (forCell2)
            {
                CellArray[Number2].ChangeCellState(Cell.Player);
            }

        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            GetLocalMousePos.X = e.X;
            GetLocalMousePos.Y = e.Y;

            if (validCell(GNumber1))
            {
                if (MouseOnRectOver(e.X, e.Y, 2) && !side(GNumber1, 3) && !side(GNumber1, 4))
                {
                    int Number2 = SearchCell(new Point(CellArray[GNumber1].GetCellXY().X, CellArray[GNumber1].GetCellXY().Y + 1));
                    CellArray[Number2].SetStick(Stick.T);
                };
                if (MouseOnRectOver(e.X, e.Y, 3) && !side(GNumber1, 1) && !side(GNumber1, 2))
                {
                    CellArray[GNumber1].SetStick(Stick.T);
                };
                if (MouseOnRectOver(e.X, e.Y, 5) && !side(GNumber1, 1) && !side(GNumber1, 3))
                {
                    CellArray[GNumber1].SetStick(Stick.L);
                };
                if (MouseOnRectOver(e.X, e.Y, 6) && !side(GNumber1, 2) && !side(GNumber1, 4))
                {
                    CellArray[GNumber1+1].SetStick(Stick.L);
                };
                if(drawn) MainImplementation(GNumber1);
            }

            //if ((CellArray[GNumber1].GetCellState() != Cell.CellState.Empty) ) 
            DisplayOX();
            this.Invalidate();
        }

        private void Form1_Activated(object sender, EventArgs e)
        {

        }

        private void DrawBorder(PaintEventArgs e)
        {
            //int i = 0;
            //Point [] Parr = {new Point(CellArray[i*i].CellXYToFormXY().X,CellArray[i*i].CellXYToFormXY().Y+s), CellArray[i*i].CellXYToFormXY(),CellArray[i*i+1].CellXYToFormXY()};
            for (int i = 1; i < Settings.r; i++) 
            {
                e.Graphics.DrawLine(new Pen(Color.Blue), new Point(CellArray[i * i].CellXYToFormXY().X, CellArray[i * i].CellXYToFormXY().Y + s), CellArray[i * i].CellXYToFormXY());
                e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[i * i].CellXYToFormXY(), CellArray[i * i + 1].CellXYToFormXY());
                //if (i > 1)
                i++;
                    e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[i * i - 1].CellXYToFormXY(), new Point(CellArray[i * i - 1].CellXYToFormXY().X +s, CellArray[i * i-1].CellXYToFormXY().Y ) );
                    e.Graphics.DrawLine(new Pen(Color.Blue), new Point(CellArray[i * i - 1].CellXYToFormXY().X + s, CellArray[i * i - 1].CellXYToFormXY().Y), CellArray[(i + 1) * (i + 1) - 1].CellXYToFormXY());
                i--;
            }
            for (int i = 2; i < Settings.r + 1; i++) 
            {
                e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[Settings.n - i * i].CellXYToFormXY(), new Point(CellArray[Settings.n - i * i].CellXYToFormXY().X, CellArray[Settings.n - i * i].CellXYToFormXY().Y + s));
                e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[Settings.n - (i - 1) * (i - 1)].CellXYToFormXY(), new Point(CellArray[Settings.n - i * i].CellXYToFormXY().X, CellArray[Settings.n - i * i].CellXYToFormXY().Y + s));
                i--;
                e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[Settings.n - i * i - 1].CellXYToFormXY().X, CellArray[Settings.n - i * i - 1].CellXYToFormXY().Y + s, CellArray[Settings.n - i * i - 1].CellXYToFormXY().X + s, CellArray[Settings.n - i * i - 1].CellXYToFormXY().Y + s);
                e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[Settings.n - i * i - 1].CellXYToFormXY().X + s, CellArray[Settings.n - i * i - 1].CellXYToFormXY().Y, CellArray[Settings.n - i * i - 1].CellXYToFormXY().X + s, CellArray[Settings.n - i * i - 1].CellXYToFormXY().Y + s);
                i++;
            }
            //CellArray[0].SetStick(Stick.All);
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[0].CellXYToFormXY(), new Point(CellArray[0].CellXYToFormXY().X + s, CellArray[0].CellXYToFormXY().Y));
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[0].CellXYToFormXY(), new Point(CellArray[0].CellXYToFormXY().X, CellArray[0].CellXYToFormXY().Y + s));
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[3].CellXYToFormXY(), new Point(CellArray[0].CellXYToFormXY().X + s, CellArray[0].CellXYToFormXY().Y));
            //CellArray[(int)Math.Round(n / 2 - Math.Sqrt(n / 2)) + 1]
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY(), new Point(CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X + s, CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y));
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY(), new Point(CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X, CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y + s));
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2)) + 1].CellXYToFormXY(), new Point(CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X, CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y + s));
            //CellArray[(int)Math.Round(n / 2 - Math.Sqrt(n / 2)) + 1]
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY(), new Point(CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X + s, CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y));
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X + s, CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y, CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X + s, CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y + s);
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X, CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y + s, CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().X + s, CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].CellXYToFormXY().Y + s);
            //CellArray[n - 1].ChangeCellState(Cell.Player);
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[Settings.n - 1].CellXYToFormXY(), new Point(CellArray[Settings.n - 1].CellXYToFormXY().X, CellArray[Settings.n - 1].CellXYToFormXY().Y + s));
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[Settings.n - 1].CellXYToFormXY().X, CellArray[Settings.n - 1].CellXYToFormXY().Y + s, CellArray[Settings.n - 1].CellXYToFormXY().X + s, CellArray[Settings.n - 1].CellXYToFormXY().Y + s);
            e.Graphics.DrawLine(new Pen(Color.Blue), CellArray[Settings.n - 1].CellXYToFormXY().X + s, CellArray[Settings.n - 1].CellXYToFormXY().Y, CellArray[Settings.n - 1].CellXYToFormXY().X + s, CellArray[Settings.n - 1].CellXYToFormXY().Y + s);

        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            //DrawSomething();
            ;
        }

        private void DrawSomething(PaintEventArgs e)
        {
            CellArray[0].ChangeCellState(Cell.Player);
            CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2))].ChangeCellState(Cell.Player);
            CellArray[Settings.n - 1].ChangeCellState(Cell.Player);
            CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].ChangeCellState(Cell.Player);

            CellArray[(int)Math.Round(Settings.n / 2 + Math.Sqrt(Settings.n / 2))].SetStick(Stick.L);
            CellArray[2].SetStick(Stick.T);
            CellArray[(int)Math.Round(Settings.n / 2 - Math.Sqrt(Settings.n / 2)) + 1].SetStick(Stick.L);
            CellArray[Settings.n - 1].SetStick(Stick.T);
        }

         void Form1_Paint(object sender, PaintEventArgs e)
        {
            for (int i = 0; i < Settings.n; i++) CellArray[i].drawCell(e);
                DrawSomething(e);
                DrawBorder(e);
        }
    }
}